package com.store.satring.utils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.JasperRunManager;
import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
import net.sf.jasperreports.engine.util.JRLoader;

import org.hibernate.Session;
import org.hibernate.jdbc.Work;

import com.store.satring.dos.Invoice;

public class ReportUtils implements Work {

	private String reportName;
	private Map<String, Object> parameters;
	private HttpServletResponse response;
	private ServletContext context;
	private boolean isReportGenerated;

	public ReportUtils(String reportName, Map<String, Object> parameters,
			HttpServletResponse response, ServletContext context) {
		super();
		this.reportName = reportName;
		this.parameters = parameters;
		this.response = response;
		this.context = context;
	}

	public void getPdfReport(final String reportName, Map<String, Object> parameters,
			JRDataSource ds, HttpServletResponse response,
			ServletContext context) throws Exception {
		byte bytes[] = null;
		try {
			bytes = JasperRunManager.runReportToPdf(
					getCompiledReport(context, reportName), parameters, ds);
		} catch (JRException e) {
			e.printStackTrace();
		}
		response.setHeader("Content-Disposition", "attachment; filename="
				+ reportName + getTimeStamp() + ".pdf");
		response.setContentLength(bytes.length);
		ServletOutputStream outputStream = null;
		try {
			outputStream = response.getOutputStream();
			outputStream.write(bytes, 0, bytes.length);

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			outputStream.flush();
		}
	}

	@Override
	public void execute(Connection conn) throws SQLException {
		try {
			System.err.println("parameters : " + parameters);
			System.err.println("reportName : " + reportName
					);
			isReportGenerated = Boolean.TRUE;
			String subReportDIR = System.getenv("SUBREPORT_DIR");
			System.out.println("subReportDIR : " + subReportDIR);
			parameters.put("SUBREPORT_DIR", subReportDIR+"\\");
			JRXlsExporter exporter = new JRXlsExporter();
			JasperPrint jasperPrint = JasperFillManager.fillReport(
					getCompiledReport(context, reportName), parameters, conn);
			if (jasperPrint.getPages().size() > 0) {
				generateXLSAndSend(jasperPrint, exporter);
			} else {
				isReportGenerated = Boolean.FALSE;
			}
		} catch (Exception e) {
			throw new SQLException(e.getMessage(), e);
		}

	}

	private void generateXLSAndSend(JasperPrint jasperPrint,
			JRXlsExporter exporter) throws JRException, IOException {
		byte bytes[] = null;
		ByteArrayOutputStream xlsReport = new ByteArrayOutputStream();
		exporter.setParameter(JRExporterParameter.JASPER_PRINT,
				jasperPrint);
		exporter.setParameter(JRExporterParameter.OUTPUT_STREAM,
				xlsReport);
		exporter.setParameter(
				JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_COLUMNS,
				Boolean.TRUE);
		exporter.setParameter(
				JRXlsExporterParameter.IS_FONT_SIZE_FIX_ENABLED,
				Boolean.TRUE);
		exporter.setParameter(
				JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND,
				Boolean.FALSE);
		exporter.setParameter(
				JRXlsExporterParameter.IS_IGNORE_CELL_BORDER,
				Boolean.FALSE);
		exporter.setParameter(
				JRXlsExporterParameter.IS_COLLAPSE_ROW_SPAN,
				Boolean.TRUE);
		exporter.setParameter(
				JRXlsExporterParameter.IS_DETECT_CELL_TYPE,
				Boolean.TRUE);
//		exporter.setParameter(JRXlsExporterParameter.OUTPUT_FILE,
//				context.getRealPath("WEB-INF/resources/reports"));
		exporter.exportReport();
		bytes = xlsReport.toByteArray();
		response.setContentType("application/vnd.ms-excel");
		response.setHeader("Content-Disposition",
				"attachment; filename=" + reportName + getTimeStamp()
						+ ".xls");
		response.setContentLength(bytes.length);
		ServletOutputStream outputStream;
		outputStream = response.getOutputStream();
		outputStream.write(bytes, 0, bytes.length);
		outputStream.flush();
		xlsReport.close();
	}

	public JasperReport getCompiledReport(ServletContext context,
			String fileName) throws JRException {
		File reportFile = new File(context.getRealPath("WEB-INF/resources/reports/" + fileName
				+ ".jasper"));
		JasperReport jasperReport = (JasperReport) JRLoader.loadObjectFromFile(reportFile.getPath());
		return jasperReport;
	}

	public boolean executeReport() throws Exception {
		Session session = (Session) Invoice.entityManager().getDelegate();
		session.doWork(this);
		return isReportGenerated();
	}

	public String getTimeStamp() {
		String timeStamp = null;
		timeStamp = "_"
				+ new SimpleDateFormat("ddMMyyyy").format(Calendar
						.getInstance().getTime());

		return timeStamp;
	}

	public String getReportName() {
		return reportName;
	}

	public void setReportName(String reportName) {
		this.reportName = reportName;
	}

	public Map<String, Object> getParameters() {
		return parameters;
	}

	public void setParameters(Map<String, Object> parameters) {
		this.parameters = parameters;
	}

	public HttpServletResponse getResponse() {
		return response;
	}

	public void setResponse(HttpServletResponse response) {
		this.response = response;
	}

	public ServletContext getContext() {
		return context;
	}

	public void setContext(ServletContext context) {
		this.context = context;
	}

	public boolean isReportGenerated() {
		return isReportGenerated;
	}

	public void setReportGenerated(boolean isReportGenerated) {
		this.isReportGenerated = isReportGenerated;
	}
	
	
}
